﻿function formulaField(name, formula, fields) {
    var self = this; 
    this.name = name;
    this.internalName = name;
    this.formula = formula;
    this.fields = ko.observableArray(fields);
    this.aggregate = ko.observable("");
    this.format = ko.observable("{0}");
    this.fieldType = "Formula";
    this.position = 0;
    this.formatField = ko.observable("{0}");
    this.opened = ko.observable(false);
    this.openToggle = function () { this.opened(!this.opened());  }
    this.niceFormula = ko.computed(function () {
        var niceForm = self.formula;
        var i = 0;
        ko.utils.arrayForEach(self.fields(), function (field) {
            var replacer = new RegExp("\\{" + i + "\\}", "g");
            niceForm = niceForm.replace(replacer, "{" + field.name + "}");
            i++;
        });
        return niceForm; 
    }); 
}

function SPField(name, internalName, type) {
    this.name = name;
    this.formula = "";
    this.internalName = internalName;
    this.type = type;
    this.fields = [];
    this.aggregate = ko.observable("");
    this.format = ko.observable("{0}");
    this.fieldType = "SharePoint";
    this.position = 0;
    this.opened = ko.observable(false);
    this.openToggle = function () { this.opened(!this.opened()); }
    this.formatField = ko.observable("{0}");   
}

function HDIAggregatedViewConfig() {

    var self = this;
    self.waiting = ko.observable(false); 
    self.aggregates = ["Sum", "Count", "Average"];
    self.Webs = ko.observableArray([]);
    self.Web = ko.observable();
    self.Lists = ko.observableArray([]);
    self.List = ko.observable();
    self.SPFields = ko.observableArray([]);
    self.numericFields = ko.observableArray([]);
    self.selectedSPFields = ko.observableArray([]);
    self.Filter = ko.observableArray([]);
    self.FormulaFields = ko.observableArray([]);
    self.curFormulaFieldName = ko.observable(""),
    self.curFormula = ko.observable("");
    self.curFormulaFields = ko.observableArray([]);
    self.addFormulaField = function () {
        var name = self.curFormulaFieldName();
        var formula = self.curFormula();
        var fields = self.curFormulaFields();
        self.FormulaFields.push(new formulaField(name, formula, fields));
        self.curFormulaFieldName("");
        self.curFormula("");
        self.curFormulaFields([]);
    }
    self.removeFormulaField = function (field) {
        self.FormulaFields.remove(field);
    }

    self.Fields = ko.computed(function () {
        var arr = []
        ko.utils.arrayPushAll(arr, self.selectedSPFields());
        ko.utils.arrayPushAll(arr, self.FormulaFields());
        arr = arr.sort(function (a, b) { return a.position - b.position; }); 
        return arr;
    });

    self.getWebs = function () {
        self.Webs.removeAll();
        $().SPServices({
            operation: "GetAllSubWebCollection",
            completefunc: function (xData, Status) {
                var webs = [];
                $(xData.responseXML).find("Webs > Web").each(function () {
                    var $node = $(this);
                    webs.push({
                        name: $node.attr("Title"),
                        url: $node.attr("Url")
                    });
                });

                ko.utils.arrayPushAll(self.Webs(), webs)
                self.Webs.valueHasMutated();
            }
        });

    }

    self.getList = function () {
        self.Lists.removeAll();
        if (self.Web() != undefined) {
            $().SPServices({
                operation: "GetListCollection",
                webURL: self.Web().url,
                completefunc: function (xData, Status) {
                    var lists = []
                    $(xData.responseXML).find("Lists > List[ShowUser='True']").each(function () {
                        var $node = $(this);
                        lists.push({
                            name: $node.attr("Title"),
                            id: $node.attr("ID")
                        });

                    });
                    ko.utils.arrayPushAll(self.Lists(), lists);
                    self.Lists.valueHasMutated();
                }
            });
        }

    }

    self.getFields = function () {
        self.SPFields.removeAll();
        self.numericFields.removeAll();
        if (self.List() != undefined) {
            $().SPServices({
                operation: "GetList",
                webURL: self.Web().url,
                listName: self.List().name,
                completefunc: function (xData, Status) {
                    var fields = [], numerics = [];

                    $(xData.responseXML).find("Fields > Field:not([Hidden])").each(function () {
                        var $node = $(this);
                        field = new SPField($node.attr("DisplayName"), $node.attr("StaticName"), $node.attr("Type"));
                        fields.push(field);

                        if (field.type == "Number" || field.type == "Integer" || field.type == "Currency" || field.type == "Calculated") {
                            numerics.push(field);
                        }
                    });
                    ko.utils.arrayPushAll(self.SPFields(), fields)
                    self.SPFields.valueHasMutated();
                    ko.utils.arrayPushAll(self.numericFields(), numerics)
                    self.numericFields.valueHasMutated();
                }
            });
        }
    }

    self.save = function () {

        ko.utils.arrayForEach(self.Fields(), function (item) {
            item.position = $("#sortable li").index($("#sortable li:contains('"+item.name+"')"));
        });
        var fields = self.Fields().sort(function (left, right) { return left.position == right.position ? 0 : (left.position < right.position ? -1 : 1) });
        var obj =
        {
            Web: self.Web(),
            List: self.List(),
            Filter: self.Filter(),
            Fields: fields
        }
        $(".JSON").val(ko.toJSON(obj));
        $.colorbox.close();
    }


    self.Web.subscribe(function (item) {
        self.getList();

    });

    self.List.subscribe(function (item) {

        self.getFields();

    });

    self.load = function () {
        self.waiting(true);
        self.getWebs();
        if ($(".JSON").val() != "") {

            var obj = JSON.parse($(".JSON").val());

            var checkList, checkFields;

            var checkWebs = setInterval(function () {
                if (self.Webs().length != 0) {
                    ko.utils.arrayFilter(self.Webs(), function (web) {

                        if (web.name == obj.Web.name) {
                            self.Web(web);
                            //start List Loading
                            checkList = setInterval(function () {
                                if (self.Lists().length != 0) {
                                    ko.utils.arrayFilter(self.Lists(), function (list) {
                                        if (list.name == obj.List.name) {
                                            self.List(list);

                                            //start Field Loading
                                            checkFields = setInterval(function () {
                                                if (self.SPFields().length != 0) {
                                                    clearInterval(checkFields);
                                                    self.waiting(false);
                                                    ko.utils.arrayForEach(obj.Filter, function (item) {
                                                        ko.utils.arrayFilter(self.SPFields(), function (field) {
                                                            if (item.internalName == field.internalName) {
                                                                self.Filter.push(field);
                                                            }
                                                        });
                                                    });
                                                    ko.utils.arrayForEach(obj.Fields, function (item) {
                                                        if (item.fieldType == 'SharePoint') {
                                                            //Is a SPField
                                                            ko.utils.arrayFilter(self.SPFields(), function (field) {
                                                                if (item.internalName == field.internalName) {
                                                                    field.aggregate(item.aggregate);
                                                                    field.format(item.format);
                                                                    field.position = item.position;
                                                                    field.formatField(item.formatField);
                                                                    self.selectedSPFields.push(field);
                                                                }
                                                            });
                                                        } else {
                                                            //Is a Formulafield
                                                            var formField = new formulaField(item.name, item.formula, item.fields);
                                                            formField.aggregate(item.aggregate);
                                                            formField.format(item.format);
                                                            formField.position = item.position;
                                                            formField.formatField(item.formatField);
                                                            self.FormulaFields.push(formField);
                                                        }

                                                    });

                                                }

                                            }, 1000);
                                        }
                                    });
                                    clearInterval(checkList);
                                }
                            }, 1000);
                        }
                    });
                    clearInterval(checkWebs);
                }
            }, 1000);
        } else {
            self.waiting(false);
        }
    }  
    self.load(); 
}


